<template>
  <div class="upload-control" :class="size">
    <div class="upload-list">
      <div
        class="upload-list-item"
        v-for="(item, index) in fileList"
        :key="index"
      >
        <div class="icons" v-if="showIcon">
          <svg
            class="close-icon"
            viewBox="0 0 24 24"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            @click="removeItem(index)"
            v-if="!showDownload"
          >
            <circle
              cx="12"
              cy="12.0004"
              r="12"
              fill="black"
              fill-opacity="0.6"
            />
            <circle
              cx="12"
              cy="12.0004"
              r="11.5"
              stroke="white"
              stroke-opacity="0.6"
            />
            <path d="M7.33301 7.3337L16.6663 16.667" stroke="white" />
            <path d="M16.667 7.3337L7.33366 16.667" stroke="white" />
          </svg>
          <IconView class="svg-preview" @click="previewImg(item)" />
          <IconDownload3 v-if="showDownload" @click="_downloadFile(item)" />
        </div>
        <img :src="item" alt="" />
      </div>
      <div
        class="upload-btn"
        v-if="isUploadMore && showUpload"
        @click="selectFile"
      >
        <svg
          class="plus-icon"
          viewBox="0 0 48 48"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path d="M8 24.0004H40" stroke="#CCD6DE" stroke-width="3" />
          <path d="M24 8.00037L24 40.0004" stroke="#CCD6DE" stroke-width="3" />
        </svg>
        <span>{{ text ? text : $t("btnText.upload_img") }}</span>
      </div>
    </div>
  </div>
  <!-- 预览图 -->
  <template v-if="showIcon">
    <Preview ref="previewRef" :url="previewUrl"></Preview>
  </template>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, ref, watch, nextTick } from "vue";
import { message } from "ant-design-vue";

type Size = "default" | "large" | "small";
const props = withDefaults(
  defineProps<{
    fileList: string[];
    single: boolean;
    size: Size;
    customUpload: boolean;
    showIcon?: boolean;
    showUpload?: boolean;
    text?: string;
    showDownload?: boolean;
  }>(),
  {
    showIcon: true,
    size: "default",
    showUpload: true,
    showDownload: false,
  }
);

// 预览图片
const previewUrl = ref();
const previewRef = ref();
const previewImg = (url: string) => {
  previewUrl.value = url;
  nextTick(() => {
    previewRef.value.open();
  });
};

const _downloadFile = (url: string) => {
  downloadFile(url)
};

const $t = getCurrentInstance()?.appContext.config.globalProperties.$t;

const fileList = ref<string[]>(props.fileList || []);

watch(
  props,
  (n) => {
    fileList.value = n.fileList;
  },
  { deep: true }
);
const emits = defineEmits(["selectFile", "removeFile"]);
const selectFile = () => {
  let input = document.createElement("input");
  input.type = "file";
  input.accept = "image/*";
  input.click();
  input.onchange = (e) => {
    let file = e.target!.files[0];
    if (file.size > 1024 * 800) {
      message.warning($t("message.upload_img.error_1"));
      return;
    }
    emits("selectFile", file);
    if (!props.customUpload) {
      fileList.value.push(URL.createObjectURL(file));
    }
  };
};

const clearFile = () => {
  fileList.value = [];
};
const removeItem = (index: number) => {
  if (!props.customUpload) {
    fileList.value.splice(index, 1);
  }
  emits("removeFile", index);
};

const isUploadMore = computed(() => {
  if (props.single) {
    return fileList.value.length < 1;
  } else {
    return true;
  }
});

defineExpose({
  clearFile,
  selectFile,
});
</script>
<style scoped lang="less">
// 配置 size
.upload-control {
  &.large {
    .upload-list > div {
      width: 135px;
      height: 180px;
    }
  }
}
.upload-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  & > div {
    width: 120px;
    height: 160px;
    border: 1px solid #ccd6de;
    border-radius: 12px;
    overflow: hidden;
    position: relative;
  }
  .upload-list-item {
    box-sizing: content-box;
    .icons {
      position: absolute;
      right: 4px;
      top: 4px;
      display: flex;
      flex-direction: column;
      gap: 6px;
      svg {
        width: 24px;
        height: 24px;
        cursor: pointer;
      }
    }
    img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
  .upload-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    cursor: pointer;
    gap: 8px;
    font-size: 14px;
    color: #ccd6de;
    svg.plus-icon {
      width: 48px;
      height: 48px;
    }
  }
}
@media screen and (max-width: 768px) {
  .upload-control {
    .upload-list {
      gap: 56px;
      & > div {
        width: 850px;
        height: 850px;
        border-radius: 51px 51px 51px 51px;
      }
      .upload-list-item {
        .icons {
          right: 20px;
          top: 20px;
          svg {
            width: 123px;
            height: 123px;
            &.svg-preview {
              display: none;
            }
          }
        }
      }
      .upload-btn {
        gap: 41px;
        font-size: 72px;
        svg.plus-icon {
          width: 246px;
          height: 246px;
        }
      }
    }
    &.large {
      .upload-list > div {
        width: 614px;
        height: 819px;
        border-radius: 51px 51px 51px 51px;
      }
    }
  }
}
</style>
